package mail.db;


import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Connection;

/**
 * Used to make a single connection to the database for all other classes to use
 */
public class DataBase { 
	private static final String serverName = "localhost";
	private static final String database = "mail";
	private static final String username = "mail";
	private static final String password = "mail";
	
	private final Connection conn;
	private int queryCounter;
	
	/**
	 * Create a new database connection
	 */
	private DataBase() {
		System.out.println("DataBase connection started");
		Connection tempConn;
		
		try {
			Class.forName ("com.mysql.jdbc.Driver").newInstance();
		} catch (InstantiationException e) {
			System.out.println("InstantiationException:\n"+e.getMessage());
		} catch (IllegalAccessException e) {
			System.out.println("IllegalAccessException:\n"+e.getMessage());
		} catch (ClassNotFoundException e) {
			System.out.println("ClassNotFoundException:\n"+e.getMessage());
		}
		
		String url = "jdbc:mysql://" + serverName +  "/" + database;
		
		try {
			tempConn = DriverManager.getConnection(url, username, password);
		} catch (SQLException e) {
			System.out.println("Could not connect to database!");
			tempConn = null;
		}
		
		conn = tempConn;
		queryCounter = 0;
	}
	
	/**
	 * @return Get the DataBase connection
	 */
	public Connection getConn() { return conn; }
	
	/**
	 * Execute a SELECT query on the database
	 * @param query		MySQL query to execute
	 * @return			ResultSet from query
	 * @throws SQLException
	 */
	public final ResultSet executeQuery(String query) throws SQLException {		
		if (conn == null) {
			System.err.println("No connection for query!");
			return null;
		} else {
			queryCounter++;
			Statement s = conn.createStatement();
			
			s.executeQuery(query);
			
			return s.getResultSet();
		}
	}
	
	/**
	 * Execute a INSERT or UPDATE MySQL query on the database
	 * @param query		MySQL query to execute
	 * @return			ID of insert query or 0
	 * @throws SQLException
	 */
	public final int executeUpdate(String query) throws SQLException {
		if (conn == null) {
			System.err.println("No connection for query!");
			return 0;
		} else {
			queryCounter++;
			Statement s = conn.createStatement();
			s.executeUpdate(query);
			
			try {
				ResultSet rs = s.getGeneratedKeys();
				rs.first();
				return rs.getInt(1);
			} catch (SQLException e) {
				return 0;
			}
		}
	}
	
	/**
	 * Return the number of rows in a ResultSet
	 * @param rs	ResultSet to check
	 * @return		Rows in rs
	 */
	public final int getRows(ResultSet rs) {
		int rows = 0;
		try {
			rs.last();
			rows = rs.getRow();
			rs.first();
		} catch (SQLException e) {
			rows = -1;
			e.printStackTrace();
		}
		
		return rows;
	}
	
	public int getQueryCount() { return queryCounter; }
	
	/**
	 * Singleton holder class for DataBase
	 */
	private static class DataBaseHolder { 
		private final static DataBase INSTANCE = new DataBase();
	}
 
	/**
	 * Returns only instance of DataBase
	 * @return	Instance of DataBase
	 */
	public static DataBase getInstance() {
		return DataBaseHolder.INSTANCE;
	}
}
